package aufgabe1.teilaufgabe2;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import aufgabe1.teilaufgabe1.Algorithm;

public class TestListe {

	private long timeStartlocal;
	private long timeEndlocal;

	public static int myRandom(int high) {
		return (int) (Math.random() * high);
	}

	@Test
	public void testIsEmpty() {
		Listen aaa = new Listen();
		assertEquals(aaa.isEmpty(), true);
	}

	@Test
	public void testConsFirstElementEmpty() {
		System.out.println("Test testConsFirstElementEmpty");
		Listen aaa = new Listen();
		assertEquals(aaa.isEmpty(), true);
		timeStartlocal = System.nanoTime();
		aaa.cons(1);
		timeEndlocal = System.nanoTime();
		System.out.println("Zugriffszeit: " + (timeEndlocal - timeStartlocal));
		System.out.println("Zugriffe: " + aaa.getCounter());
		assertEquals(aaa.isEmpty(), false);
	}

	@Test
	public void testConsElementsRightPositions() {
		Listen aaa = new Listen();
		assertEquals(aaa.isEmpty(), true);
		aaa.cons(1);
		aaa.cons(2);
		aaa.cons(3);
		aaa.cons(4);
		aaa.cons(5);
		aaa.cons(6);
		aaa.cons(7);
		aaa.cons(8);
		aaa.cons(9);
		aaa.cons(10);
		assertEquals(aaa.isEmpty(), false);
		assertEquals(aaa.get(0), 10);
		assertEquals(aaa.get(1), 9);
		assertEquals(aaa.get(2), 8);
		assertEquals(aaa.get(3), 7);
		assertEquals(aaa.get(4), 6);
		assertEquals(aaa.get(5), 5);
		assertEquals(aaa.get(6), 4);
		assertEquals(aaa.get(7), 3);
		assertEquals(aaa.get(8), 2);
		assertEquals(aaa.get(9), 1);

	}

	@Test
	public void testHeapFirst() {
		Listen aaa = new Listen();
		aaa.cons(1);
		aaa.cons(1);
		// aaa.head();
		// assertEquals(aaa.isEmpty(),true);
		// assertEquals(aaa.get(0),null);
	}

	@Test
	public void testHead() {
		System.out.println("Test testHead");
		Listen aaa = new Listen();
		assertEquals(aaa.isEmpty(), true);
		aaa.cons(1);
		aaa.cons(2);
		aaa.cons(3);
		aaa.cons(4);
		timeStartlocal = System.nanoTime();
		aaa.head();
		timeEndlocal = System.nanoTime();
		System.out.println("Zugriffszeit: " + (timeEndlocal - timeStartlocal));
		System.out.println("Zugriffe: " + aaa.getCounter());
		assertEquals(aaa.isEmpty(), false);
		assertEquals(aaa.get(0), 3);

	}

	@Test
	public void testConsManyElements() {
		System.out
				.println("################testConsManyElements###############");
		Listen aaa = new Listen();
		assertEquals(aaa.isEmpty(), true);
		timeStartlocal = System.currentTimeMillis();
		for (int i = 0; i < 10000; i++) {
			aaa.cons(i);
			// System.out.println(i);
		}
		timeEndlocal = System.currentTimeMillis();
		System.out.println("Zugriffszeit: " + (timeEndlocal - timeStartlocal));
		System.out.println("Zugriffe: " + aaa.getCounter());

	}

	@Test
	public void testConsLastElements() {
		System.out
				.println("################testConsLastElements###############");
		Listen aaa = new Listen();
		timeStartlocal = System.currentTimeMillis();
		for (int i = 0; i < 10000; i++) {
			aaa.insert(i, i);
		}
		timeEndlocal = System.currentTimeMillis();
		System.out.println("Zugriffszeit: " + (timeEndlocal - timeStartlocal));
		System.out.println("Zugriffe: " + aaa.getCounter());
	}

	@Test
	public void testRandom() {
		List<Double> list = new ArrayList();
		for (int j = 0; j < 10; j++) {

			System.out.println("################testRandom###############");
			Listen aaa = new Listen();
			timeStartlocal = System.currentTimeMillis();
			for (int i = 0; i < 10000; i++) {
				int ran = myRandom(i);

				aaa.insert(ran, i);
			}
			timeEndlocal = System.currentTimeMillis();
			long time = (timeEndlocal - timeStartlocal);
			double result = new Long(time).doubleValue();
			System.out.println("Zugriffszeit: " + time);
			System.out.println("Zugriffe: " + aaa.getCounter());

			list.add(result);
		}

		System.out.println();
		System.out.println("Varianz: " + Algorithm.var(list));
		System.out.println("Mittelwert: " + Algorithm.middle(list));
	}

	@Test
	public void testRandomIterativ() {
		System.out.println("################Iterativ#####################");
		List<Double> list = new ArrayList();

		Listen aaa = new Listen();
		

		for (int i = 0; i < 100; i++) {
			int ran = myRandom(i);

			aaa.insert(ran, i);
		}
		aaa.setCounter(0);
		
		aaa.insert(40, 20);
		

		System.out.println("Zugriffe: " + aaa.getCounter());

		System.out.println();

	}

	@Test
	public void testRandomRekursiv() {
		System.out.println("################Rekursiv#####################");
		List<Double> list = new ArrayList();

		Listen aaa = new Listen();
		

		for (int i = 0; i < 100; i++) {
			int ran = myRandom(i);

			aaa.insert(ran, i);
		}
		aaa.setCounter(0);
		aaa.insertRec(40, 20);
		
		
		System.out.println("Zugriffe: " + aaa.getCounter());
	}
	
	

}
